package com.quanquan.store.service;

import DTO.PageDTO;
import DTO.image.Image;
import DTO.image.ImageDTO;
import com.quanquan.store.configBean.RabbitSender;
import com.quanquan.store.dto.AdsenceDTO;
import com.quanquan.store.dto.BannerDTO;
import com.quanquan.store.dto.IdDTO;
import com.quanquan.store.entity.Adsence;
import com.quanquan.store.entity.Banner;
import com.quanquan.store.entity.BannerAdsence;
import com.quanquan.store.repository.BannerRepository;
import com.quanquan.store.request.AdsenceRequest;
import com.quanquan.store.request.BannerRequest;
import commond.ImageOutPut;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import utils.DateUtils;
import utils.StringUtil;
import utils.UUIDGenerator;

import javax.persistence.criteria.Predicate;
import java.util.*;

/**
 * @ClassName:BannerService
 * @Description:TODO
 * @Author:xiongjunbao
 * @Date:2019/3/14 10:40
 * @Version 1.0
 */
@Service
public class BannerService {

    @Autowired
    private BannerRepository bannerRepository;
    @Autowired
    private BannerAdsenceService bannerAdsenceService;
    @Autowired
    private AdsenceService adsenceService;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private RabbitSender rabbitSender;

    /**
     * 新增banner
     *
     * @param request
     * @return
     */
    public boolean saveBanner(BannerRequest request) {
        Banner banner = new Banner();
        Date date = new Date();
        banner.setId(UUIDGenerator.getUUID());
        banner.setCreateTime(DateUtils.dateToString(date, DateUtils.TIMESTAMP));
        banner.setUpdateTime(DateUtils.dateToString(date, DateUtils.TIMESTAMP));
        if (StringUtil.isNotEmpty(request.getEndTime())){
            banner.setEndTime(DateUtils.dateToString(DateUtils.strToDate(request.getEndTime() + ":00", DateUtils.TIMESTAMP), DateUtils.TIMESTAMP));
        }
        if (StringUtil.isNotEmpty(request.getStartTime())){
            banner.setStartTime(DateUtils.dateToString(DateUtils.strToDate(request.getStartTime() + ":00", DateUtils.TIMESTAMP), DateUtils.TIMESTAMP));
        }
        banner.setStatusShow(0);
        banner.setStatusRemove(0);
        banner.setStatus(0);
        banner.setBannerText(request.getBannerText());
        banner.setBannerDesc(request.getBannerDesc());
        banner.setSortOrder(request.getSortOrder());
        banner.setLinkValue(request.getLinkValue());
        banner.setLinkType(request.getLinkType());
        banner.setActivityId(request.getActivityId());
        //绑定广告位与banner
        if (request.getAdsenceId() != null) {
            banner.setAdsenceId(request.getAdsenceId());
        }
        List<String> imageIdList = new LinkedList<>();
        imageIdList.add(request.getImageId());
        bandingImageShip(banner.getId(), imageIdList);
        bannerRepository.saveAndFlush(banner);
        return true;
    }

    /**
     * 绑定banner图片
     *
     * @param bannerId
     * @param imageIdlist
     */
    private void bandingImageShip(String bannerId, List<String> imageIdlist) {
        ImageOutPut imageOutPut = new ImageOutPut();
        imageOutPut.setForeignKeyId(bannerId);
        imageOutPut.setImageSource("banner");
        //通过mq消息队列发送给资源模块绑定图片关系
//        amqpTemplate.convertAndSend("image.exchange", "image.banner", JsonUtil.toJson(imageOutPut));

        Map<String, Object> properties = new HashMap<>();
        properties.put("imageIds", imageIdlist);
        String exchange = "image.exchange";
        String routingKey = "image.banner";

        rabbitSender.sendMessageToMQ(imageOutPut, properties, exchange, routingKey);
    }

    /**
     * 修改banner信息
     *
     * @param request
     * @return
     */
    public boolean updateBanner(BannerRequest request) {
        Date date = new Date();
        Banner banner = bannerRepository.findByBannerId(request.getId());
        if (banner == null) {
            banner = new Banner();
            banner.setCreateTime(DateUtils.dateToString(date, DateUtils.TIMESTAMP));
        }
        banner.setUpdateTime(DateUtils.dateToString(date, DateUtils.TIMESTAMP));
        banner.setEndTime(DateUtils.dateToString(DateUtils.strToDate(request.getEndTime() + ":00", DateUtils.TIMESTAMP), DateUtils.TIMESTAMP));
        banner.setStartTime(DateUtils.dateToString(DateUtils.strToDate(request.getStartTime() + ":00", DateUtils.TIMESTAMP), DateUtils.TIMESTAMP));
        banner.setBannerText(request.getBannerText());
        banner.setBannerDesc(request.getBannerDesc());
        banner.setSortOrder(request.getSortOrder());
        banner.setStatusShow(0);
        banner.setStatusRemove(0);
        banner.setStatus(0);
        banner.setLinkValue(request.getLinkValue());
        banner.setLinkType(request.getLinkType());
        banner.setActivityId(request.getActivityId());
        if (request.getAdsenceId() != null) {
            banner.setAdsenceId(request.getAdsenceId());
        }
        List<String> imageIdList = new LinkedList<>();
        imageIdList.add(request.getImageId());
        bandingImageShip(banner.getId(), imageIdList);
        bannerRepository.saveAndFlush(banner);
        BannerDTO bannerDTO = new BannerDTO();
        BeanUtils.copyProperties(banner, bannerDTO);
        return true;
    }


    /**
     * 删除banner（软删除）
     *
     * @param request
     * @return
     */
    public boolean removeBanner(BannerRequest request) {
        Date date = new Date();
        Banner banner = bannerRepository.findByBannerId(request.getId());
        banner.setStatusRemove(1);
        banner.setUpdateTime(DateUtils.dateToString(date, DateUtils.TIMESTAMP));
        bannerRepository.saveAndFlush(banner);
        return true;
    }

    /**
     * 上下架
     *
     * @param request
     * @return
     */
    public boolean updateStatus(BannerRequest request) {
        Date date = new Date();
        Banner banner = bannerRepository.findByBannerId(request.getId());
        if (request.getStatus() == 0) {
            banner.setStatus(1);
            banner.setUpdateTime(DateUtils.dateToString(date, DateUtils.TIMESTAMP));
        } else {
            banner.setStatus(0);
            banner.setUpdateTime(DateUtils.dateToString(date, DateUtils.TIMESTAMP));
        }
        bannerRepository.saveAndFlush(banner);
        return true;
    }

    public PageDTO<BannerDTO> queryByCondition(BannerRequest requestBody) {
        //分页
        Integer page = null == requestBody.getPage() ? 0 : requestBody.getPage();
        Integer size = null == requestBody.getSize() ? 10 : requestBody.getSize();
        //优惠券创建时间区间
        String fromDate = requestBody.getFromDate();
        String toDate = requestBody.getToDate();
        //搜索关键词
        String keyword = requestBody.getKeyword();
        Integer statusRemove = 0;
        //排序状态
        Sort sort = new Sort(Sort.Direction.ASC, "sortOrder");
        Pageable pageable = PageRequest.of(page, size, sort);
        Page<Banner> paged = bannerRepository.findAll((Specification<Banner>) (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();

            predicates.add(criteriaBuilder.equal(root.get("statusRemove").as(Integer.class), statusRemove));

            if (StringUtil.isNotEmpty(fromDate)) {
                Date startOfDay = DateUtils.getStartOfDay(DateUtils.strToDate(fromDate, DateUtils.DATE));
                predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("startTime").as(Date.class), startOfDay));
            }
            if (StringUtil.isNotEmpty(toDate)) {
                Date endOfDay = DateUtils.getEndOfDay(DateUtils.strToDate(toDate, DateUtils.DATE));
                predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("endTime").as(Date.class), endOfDay));
            }
            if (StringUtil.isNotEmpty(keyword)) {
                List<Adsence> adsenceList = adsenceService.findListByKeyword(keyword);
                if (adsenceList.size()>0){
                    Adsence adsence = adsenceList.get(0);
                    predicates.add(criteriaBuilder.equal(root.get("adsenceId").as(String.class), adsence.getId()));
                }else{
                    Predicate p1 = criteriaBuilder.like(root.get("bannerText").as(String.class), "%" + keyword + "%");
                    Predicate p2 = criteriaBuilder.or(criteriaBuilder.like(root.get("bannerDesc").as(String.class), "%" + keyword + "%"), p1);
                    predicates.add(p2);
                }
            }

            return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
        }, pageable);
        PageDTO<BannerDTO> dto = new PageDTO<>();
        List<BannerDTO> bannerDTOS = new LinkedList<>();
        for (Banner banner : paged.getContent()){
            BannerDTO bannerDTO = formatBannerInfo(banner);
            bannerDTOS.add(bannerDTO);
        }
        dto.setTotal(paged.getTotalElements());
        dto.setList(bannerDTOS);
        dto.setPage(page);
        dto.setPageSize(size);
        dto.setKeyword(requestBody.getKeyword());
        dto.setTotalPage(paged.getTotalPages());
        dto.setFromDate(fromDate);
        dto.setToDate(toDate);
        return dto;
    }

    /**
     * 前后端通用接口，查询未下架banner列表
     *
     * @param request
     * @return
     */
    public List<BannerDTO> queryList(BannerRequest request) {
        Date date = new Date();
        List<BannerDTO> bannerDTOList = new LinkedList<>();
        List<Banner> bannerList = null;
        //分页
        Sort sort = new Sort(Sort.Direction.ASC, "sortOrder");
        Integer page = request.getPage() == null ? 0 : request.getPage();
        Integer size = request.getSize() == null ? 100 : request.getSize();
        Pageable pageable = PageRequest.of(page, size, sort);
        Banner banner = new Banner();
        banner.setStatus(1);
        banner.setStatusRemove(0);
        Example<Banner> example = Example.of(banner);
        Page<Banner> findAll = bannerRepository.findAll(example, pageable);
        bannerList = findAll.getContent();
        for (Banner localbanner : bannerList) {
            BannerDTO bannerDTO = new BannerDTO();
            //TODO
            if (StringUtil.isNotEmpty(localbanner.getStartTime()) && StringUtil.isNotEmpty(localbanner.getEndTime())) {
                if (date.before(DateUtils.stringToDate(localbanner.getStartTime(), DateUtils.TIMESTAMP)) || date.after(DateUtils.stringToDate(localbanner.getEndTime(), DateUtils.TIMESTAMP))) {
                    continue;
                }
            }
            BeanUtils.copyProperties(localbanner, bannerDTO);
            AdsenceDTO adsenceDTO = adsenceService.query(localbanner.getAdsenceId());
            bannerDTO.setAdsenceDTO(adsenceDTO);
            List<ImageDTO> imageDTOS = new LinkedList<>();
            IdDTO idDTO = new IdDTO();
            idDTO.setForeignKeyId(localbanner.getId());
            ImageDTO imageDTO = restTemplate.postForObject("http://quanquan-resource/image/image_query", idDTO, ImageDTO.class);
            imageDTOS.add(imageDTO);
            bannerDTO.setImageDTOList(imageDTOS);
            bannerDTOList.add(bannerDTO);
        }
        return bannerDTOList;
    }

    /**
     * banner详情
     *
     * @param id
     * @return
     */
    public BannerDTO query(String id) {
        Banner banner = bannerRepository.findByBannerId(id);
        return formatBannerInfo(banner);
    }


    /**
     * 通过广告类型，广告位查找banner列表
     *
     * @param request
     * @return
     */
    public List<BannerDTO> queryListByBannerType(AdsenceRequest request) {
        List<BannerDTO> bannerDTOList = new LinkedList<>();
        Integer page = request.getPage() == null ? 0 : request.getPage();
        Integer size = request.getSize() == null ? 100 : request.getSize();
        List<Adsence> adsenseList = adsenceService.queryByBannerType(request.getBannerType(), page, size);
        for (Adsence adsense : adsenseList) {
            List<BannerAdsence> bannerAdsenses = bannerAdsenceService.queryByAdsenceId(adsense.getId());
            for (BannerAdsence bannerAdsense : bannerAdsenses) {
                BannerDTO bannerDTO = query(bannerAdsense.getBannerId());
                bannerDTOList.add(bannerDTO);
            }
        }
        return bannerDTOList;
    }

    /**
     * 通过广告类型，广告位查找banner列表
     *
     * @param request
     * @return
     */
    public List<BannerDTO> queryByAdsenseId(BannerRequest request) {
        List<BannerDTO> bannerDTOList = new LinkedList<>();
        Integer page = request.getPage() == null ? 0 : request.getPage();
        Integer size = request.getSize() == null ? 100 : request.getSize();
        List<Banner> banners = null;
        if (StringUtil.isEmpty(request.getAdsenceId())) {
            Sort sort = new Sort(Sort.Direction.ASC, "sortOrder");
            Pageable pageable = PageRequest.of(page, size, sort);
            Page<Banner> pageBanner = bannerRepository.findAll(pageable);
            banners = pageBanner.getContent();
        } else {
            Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, "b.createTime");
            banners = bannerRepository.findByAdsenseIdNew(request.getId(), pageable);
        }
        for (Banner banner : banners) {
            bannerDTOList.add(formatBannerInfo(banner));
        }
        return bannerDTOList;
    }


    private BannerDTO formatBannerInfo(Banner banner) {
        BannerDTO bannerDTO = new BannerDTO();
        //TODO
        AdsenceDTO adsenceDTO = adsenceService.query(banner.getAdsenceId());
        bannerDTO.setAdsenceDTO(adsenceDTO);
        BeanUtils.copyProperties(banner, bannerDTO);
        List<ImageDTO> imageDTOS = new LinkedList<>();
        IdDTO idDTO = new IdDTO();
        idDTO.setForeignKeyId(banner.getId());
        ImageDTO imageDTO = restTemplate.postForObject("http://quanquan-resource/image/image_query", idDTO, ImageDTO.class);
        if (imageDTO != null) {
            imageDTOS.add(imageDTO);
            List<Image> imageDTOs = imageDTO.getImageDTOs();
            if (imageDTOS != null && imageDTOS.size() > 0) {
                Image image = imageDTOs.get(0);
                bannerDTO.setImageAddress(image.getImageAddress());
                bannerDTO.setImageId(image.getId());
            }
        }
        bannerDTO.setImageDTOList(imageDTOS);
        return bannerDTO;
    }

}
